home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Scope / Scope Disk #157 (199x)(Scope PD)(US)[WB].zip / Scope Disk #157 (199x)(Scope PD)(US)[WB].adf / LockDevice / LockDevice-Handler.c < prev    next >
C/C++ Source or Header  |  1990-10-25  |  6KB  |  299 lines

  1. /* $Revision Header * Header built automatically - do not edit! *************
  2.  *
  3.  *    (C) Copyright 1990 by MXM
  4.  *
  5.  *    Name .....: LockDevice-Handler.c
  6.  *    Created ..: Tuesday 26-Jun-90 14:19
  7.  *    Revision .: 1
  8.  *
  9.  *    Date            Author          Comment
  10.  *    =========       ========        ====================
  11.  *    26-Jun-90       Olsen           Created this file!
  12.  *
  13.  * $Revision Header ********************************************************/
  14.  
  15.     /* Global lock segment. */
  16.  
  17. struct LockSeg            *LSeg;
  18.  
  19.     /* Prototypes. */
  20.  
  21. BYTE                StrCmp(char *a,char *b);
  22. struct FileSysStartupMsg *    FindDevice(char *DevName);
  23. BYTE                CreatePatch(char *DeviceName,char *PassWord);
  24. extern VOID            NewBeginIO(VOID);
  25. VOID *                PatchedBeginIO(struct IOExtTD *Request);
  26. LONG                _main(VOID);
  27.  
  28.     /* StrCmp(char *a,char *b):
  29.      *
  30.      *    Do a string comparison ignoring case.
  31.      */
  32.  
  33. BYTE
  34. StrCmp(char *a,char *b)
  35. {
  36.     for( ; toupper(*a) == toupper(*b) ; a++, b++)
  37.     {
  38.         if(!(*a))
  39.             return(0);
  40.     }
  41.  
  42.     return(1);
  43. }
  44.  
  45.     /* FindDevice(char *DevName):
  46.      *
  47.      *    Find the environment data for filing system device.
  48.      */
  49.  
  50. struct FileSysStartupMsg *
  51. FindDevice(char *DevName)
  52. {
  53.     char            *Pointer,Name[257];
  54.     struct DeviceNode    *DevInfo;
  55.     SHORT             i;
  56.  
  57.     Forbid();
  58.  
  59.     DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
  60.  
  61.     while(DevInfo)
  62.     {
  63.         if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
  64.         {
  65.             Pointer = (char *)BADDR(DevInfo -> dn_Name);
  66.  
  67.             for(i = 0 ; i < Pointer[0] ; i++)
  68.                 Name[i] = Pointer[i + 1];
  69.  
  70.             Name[Pointer[0]    ] = ':';
  71.             Name[Pointer[0] + 1] = 0;
  72.  
  73.             if(!StrCmp(Name,DevName))
  74.             {
  75.                 Permit();
  76.                 return(BADDR(DevInfo -> dn_Startup));
  77.             }
  78.         }
  79.  
  80.         DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  81.     }
  82.  
  83.     Permit();
  84.  
  85.     return(NULL);
  86. }
  87.  
  88.     /* CreatePatch(char *DeviceName,char *PassWord):
  89.      *
  90.      *    Create a BeginIO patch for a given filing device.
  91.      */
  92.  
  93. BYTE
  94. CreatePatch(char *DeviceName,char *PassWord)
  95. {
  96.     struct Patch            *NewPatch,*TempPatch = LSeg -> RootPatch;
  97.     struct FileSysStartupMsg    *Startup;
  98.     char                *DriverName;
  99.  
  100.         /* Try to find the environment vector. */
  101.  
  102.     if(Startup = FindDevice(DeviceName))
  103.     {
  104.             /* Allocate memory for the patch. */
  105.  
  106.         if(NewPatch = (struct Patch *)AllocMem(sizeof(struct Patch),MEMF_PUBLIC | MEMF_CLEAR))
  107.         {
  108.                 /* Allocate memory for the IORequest. */
  109.  
  110.             if(NewPatch -> Request = (struct IOExtTD *)AllocMem(sizeof(struct IOExtTD),MEMF_PUBLIC | MEMF_CLEAR))
  111.             {
  112.                 NewPatch -> Request -> iotd_Req . io_Message . mn_Node . ln_Type    = NT_MESSAGE;
  113.                 NewPatch -> Request -> iotd_Req . io_Message . mn_Length        = sizeof(struct IOExtTD);
  114.  
  115.                     /* Remember the name of the device driver. */
  116.  
  117.                 DriverName = (char *)((ULONG)BADDR(Startup -> fssm_Device) + 1);
  118.  
  119.                     /* Open the device driver. */
  120.  
  121.                 if(!OpenDevice(DriverName,Startup -> fssm_Unit,NewPatch -> Request,Startup -> fssm_Flags))
  122.                 {
  123.                         /* Remember the device pointer. */
  124.  
  125.                     NewPatch -> Device = NewPatch -> Request -> iotd_Req . io_Device;
  126.  
  127.                         /* Copy the password. */
  128.  
  129.                     if(PassWord)
  130.                         strcpy(NewPatch -> PassWord,PassWord);
  131.  
  132.                         /* Copy the name of the filing device. */
  133.  
  134.                     strcpy(NewPatch -> UnitName,DeviceName);
  135.  
  136.                         /* Copy the name of the device driver. */
  137.  
  138.                     strcpy(NewPatch -> DriverName,DriverName);
  139.  
  140.                     Disable();
  141.  
  142.                         /* Remember old BeginIO vector. */
  143.  
  144.                     NewPatch -> OldBeginIO = (VOID *)SetFunction((struct Library *)NewPatch -> Device,DEV_BEGINIO,NewBeginIO);
  145.  
  146.                         /* Add the patch to the patch list. */
  147.  
  148.                     while(TempPatch)
  149.                     {
  150.                         if(!TempPatch -> NextPatch)
  151.                         {
  152.                             TempPatch -> NextPatch = NewPatch;
  153.  
  154.                             Enable();
  155.  
  156.                             return(TRUE);
  157.                         }
  158.  
  159.                         TempPatch = TempPatch -> NextPatch;
  160.                     }
  161.  
  162.                     LSeg -> RootPatch = NewPatch;
  163.  
  164.                     Enable();
  165.  
  166.                     return(TRUE);
  167.                 }
  168.  
  169.                 FreeMem(NewPatch -> Request,sizeof(struct IOExtTD));
  170.             }
  171.  
  172.             FreeMem(NewPatch,sizeof(struct Patch));
  173.         }
  174.     }
  175.  
  176.     return(FALSE);
  177. }
  178.  
  179.     /* PatchedBeginIO(struct IOExtTD *Request):
  180.      *
  181.      *    Our patched BeginIO routine. Note: this code is
  182.      *    shared between a number of calling tasks and has
  183.      *    to be reentrant.
  184.      */
  185.  
  186. VOID *
  187. PatchedBeginIO(struct IOExtTD *Request)
  188. {
  189.     struct Patch    *Patch        = LSeg -> RootPatch;
  190.     VOID        *JumpAddress    = NULL;
  191.  
  192.     Disable();
  193.  
  194.         /* Find the patch for this device. */
  195.  
  196.     while(Patch)
  197.     {
  198.         if(Patch -> Device == Request -> iotd_Req . io_Device)
  199.             break;
  200.  
  201.         Patch = Patch -> NextPatch;
  202.     }
  203.  
  204.         /* Got it! Remember the old BeginIO vector. */
  205.  
  206.     if(Patch)
  207.         JumpAddress = Patch -> OldBeginIO;
  208.  
  209.     Enable();
  210.  
  211.     if(!Patch)
  212.         Request -> iotd_Req . io_Error = TDERR_NotSpecified;
  213.     else
  214.     {
  215.         switch(Request -> iotd_Req . io_Command & ~TDF_EXTCOM)
  216.         {
  217.                 /* Reject illegal commands. */
  218.  
  219.             case CMD_WRITE:
  220.             case TD_FORMAT:
  221.             case TD_RAWWRITE:    Request -> iotd_Req . io_Error    = TDERR_WriteProt;
  222.                         return(NULL);
  223.  
  224.                 /* Disk is write protected. */
  225.  
  226.             case TD_PROTSTATUS:    Request -> iotd_Req . io_Error    = 0;
  227.                         Request -> iotd_Req . io_Actual    = ~0;
  228.                         return(NULL);
  229.  
  230.             default:        break;
  231.         }
  232.     }
  233.  
  234.         /* Return to the interface code. */
  235.  
  236.     return(JumpAddress);
  237. }
  238.  
  239.     /* _main():
  240.      *
  241.      *    Handler entry point.
  242.      */
  243.  
  244. LONG
  245. _main()
  246. {
  247.     struct Process        *ThisProcess = (struct Process *)SysBase -> ThisTask;
  248.     ULONG             SignalSet;
  249.  
  250.         /* Called from shell? */
  251.  
  252.     if(ThisProcess -> pr_CLI || !(LSeg = (struct LockSeg *)FindPort(PORTNAME)))
  253.         return(-1);
  254.  
  255.         /* Initialize the global MsgPort. */
  256.  
  257.     LSeg -> SignalPort . mp_SigBit    = SIGBREAKB_CTRL_E;
  258.     LSeg -> SignalPort . mp_SigTask    = ThisProcess;
  259.     LSeg -> SignalPort . mp_Flags    = PA_SIGNAL;
  260.  
  261.         /* Add the child entry and ring back. */
  262.  
  263.     LSeg -> Child = (struct Task *)ThisProcess;
  264.  
  265.     Signal(LSeg -> Father,LSeg -> HandShake);
  266.  
  267.     for(;;)
  268.     {
  269.         SignalSet = Wait(SIG_PORT | SIG_QUIT);
  270.  
  271.             /* A new patch request came in. */
  272.  
  273.         if(SignalSet & SIG_PORT)
  274.         {
  275.             struct LockMsg *Message;
  276.  
  277.             while(Message = (struct LockMsg *)GetMsg(&LSeg -> SignalPort))
  278.             {
  279.                 Message -> Success = CreatePatch(Message -> DeviceName,Message -> PassWord);
  280.  
  281.                 ReplyMsg((struct Message *)Message);
  282.             }
  283.         }
  284.  
  285.             /* Deallocate the handler. */
  286.  
  287.         if(SignalSet & SIG_QUIT)
  288.         {
  289.             LSeg -> Child = NULL;
  290.  
  291.             Forbid();
  292.  
  293.             Signal(LSeg -> Father,LSeg -> HandShake);
  294.  
  295.             return(0);
  296.         }
  297.     }
  298. }
  299.